import os
import random
import subprocess
import threading

from flask import Flask, request, jsonify, send_file
import os
import time
from threading import Thread
from datetime import datetime
import shutil
import schedule
import time
from threading import Thread
import queue

from main import run_scheduler

app = Flask(__name__)


# 定义文件保存的根目录
BASE_DIR = "d://human/assets"

# 合成进行中标记
is_processing = False

# 推流视频根目录
BASE_RESULT_DIR = "d://human"

# 随机视频列表
random_videos = ['d://human/random/random1.mp4','d://human/random/random2.mp4']

# 创建队列保存任务
q = queue.Queue()



def uniformize_videos(video_paths, temp_dir="D://human/temp/"):
    """
    将所有视频转换为统一格式。

    :param video_paths: 本地视频文件路径列表
    :param temp_dir: 临时目录用于存放转换后的视频，默认为"D://human/temp/"
    :return: 转换后视频的路径列表
    """
    os.makedirs(temp_dir, exist_ok=True)
    uniform_videos = []
    for i, video in enumerate(video_paths):
        output_path = os.path.join(temp_dir, f"uniform_{i}.mp4")
        command = ['ffmpeg', '-i', video, '-c:v', 'libx264', '-c:a', 'aac',
                   '-vf', 'scale=1080:1920',  # 设置分辨率为 1080x1920
                   '-movflags', '+faststart', '-y', output_path]
        try:
            subprocess.run(command, check=True)
            uniform_videos.append(output_path)
        except subprocess.CalledProcessError as e:
            print(f"转换视频{video}时出错：{e}")
    return uniform_videos

def merge_videos_randomly_with_overlay(video_paths, overlay_video, overlay_start_time, overlay_duration, output_path="D://human/output.mp4", random_status=True):
    # 随机打乱视频文件顺序
    if random_status is None:
        random_status = True

    if random_status == True:
       random.shuffle(video_paths)

    # 使用uniformize_videos函数转换为统一格式
    uniform_videos = uniformize_videos(video_paths)

    # 创建一个临时文件保存输入文件列表
    list_file_path = "D://human/input_list.txt"
    with open(list_file_path, 'w') as file:
        for video in uniform_videos:
            file.write(f"file '{os.path.abspath(video)}'\n")

    # 合成视频
    merged_video_path = "D://human/merged_video.mp4"
    command = ['ffmpeg', '-f', 'concat', '-safe', '0', '-i', list_file_path,
               '-c', 'copy', '-movflags', '+faststart', '-y', merged_video_path]
    subprocess.run(command, check=True)

    # 使用overlay视频覆盖在合并好的视频上，从指定时间开始并在指定时间内结束
    final_command =  ['ffmpeg', '-i', merged_video_path, '-i', overlay_video,
                      '-filter_complex',
                      f"[1:v]trim=duration={overlay_duration},setpts=PTS-STARTPTS,scale=150:150[v1];"
                      f"[0:v][v1]overlay=W-w-10:10:enable='between(t,{overlay_start_time},{overlay_start_time + overlay_duration})'[v];"
                      "[v]transpose=1[vout]",  # 在这里添加了旋转90度的滤镜，并将输出标记为[vout]
                      '-map', '[vout]', '-map', '0:a', # 将旋转后的视频流[vout]和原始音频流映射到输出
                      '-c:v', 'libx264', '-c:a', 'aac',
                      '-movflags', '+faststart', '-y', output_path]

    # 执行命令
    try:
        subprocess.run(final_command, check=True)
        print("视频合并并叠加成功！")
        return True, "视频合并并叠加成功！"
    except subprocess.CalledProcessError as e:
        print(f"视频合并并叠加失败，请检查输入文件和命令。错误信息：{e}")
        return False, "视频合并并叠加失败！"
    finally:
        # 清理临时文件和转换后的临时视频
        if os.path.exists(list_file_path):
            os.remove(list_file_path)
        for video in uniform_videos:
            os.remove(video)
        if os.path.exists(merged_video_path):
            os.remove(merged_video_path)

# # 示例调用
# video_files = ["D://videos/video1.mp4", "D://videos/video2.mp4"]
# overlay_video = "D://videos/videoB.mp4"  # 视频b的位置
# overlay_start_time = 5  # 视频b在合成视频中的开始时间为第5秒
# overlay_duration = 10   # 视频b持续播放10秒
# merge_videos_randomly_with_overlay(video_files, overlay_video, overlay_start_time, overlay_duration)

@app.route('/stop/merge/videos', methods=['POST'])
def stop_merge_videos():
    global is_processing
    is_processing = False
    print("视频合成手动结束")
    return jsonify({"success": True, "message": '视频合成手动结束'})

# 获取队列数据
@app.route('/queue/data', methods=['GET'])
def get_queue_data():
    result = []
    print("获取队列数据")
    while not q.empty():
        result.append(q.get())
    return jsonify({"success": True, "data": result})
# 删除已合成的视频
@app.route('/delete/videos', methods=['POST'])
def delete_videos():
    file_path = request.json.get("filePath")
    os.remove(file_path)
    print("删除已合成的视频" + file_path)
    return jsonify({"success": True, "message": '删除成功'})

@app.route('/merge/videos', methods=['POST'])
def merge_videos():
    #开始合成
    data = request.json
    video_files = data.get('video_files')
    random_status = data.get('random_status')


    if not all([video_files]):
        return jsonify({"success": False, "message": "缺少必要参数"}), 400
    global is_processing
    is_processing = True
    threading.Thread(target = handle_video,args=(video_files,random_status,)).start()


    return jsonify({"success": True, "message": '提交成功'})

def handle_video(video_files,random_status):
    #开启异步线程处理
    while True:
        if is_processing != True:
            print("视频推流结束")
            break
        size = q.qsize()
        if size >= 10:
            print("队列已满，等待处理...")
            time.sleep(5)
        else:
            #获取一个随机视频
            overlay_video = random.choice(random_videos)
            #随机开始时间[1-30S]
            overlay_start_time = random.randint(1,30)
            #随机播放时间[不小于5秒]
            overlay_duration = random.randint(1,30)

            filePath =  "D://human/"  + str(time.time()) +  "_output.mp4"

            success, message = merge_videos_randomly_with_overlay(video_files, overlay_video, overlay_start_time, overlay_duration, filePath,random_status)
            if success == False:
                print('合成视频失败' + message)
                break
            q.put(filePath)
        time.sleep(3)


# 文件上传接口
@app.route('/upload', methods=['POST'])
def upload_file():
    if 'file' not in request.files:
        return jsonify({"error": "No file part"}), 400

    file = request.files['file']

    if file.filename == '':
        return jsonify({"error": "No selected file"}), 400

    # 获取当前日期
    current_date = datetime.now().strftime("%Y%m%d")
    save_dir = os.path.join(BASE_DIR, current_date)

    # 确保日期目录存在
    if not os.path.exists(save_dir):
        os.makedirs(save_dir)

    # 保存文件
    file_path = os.path.join(save_dir, file.filename)
    file.save(file_path)

    # 返回文件的URL
    file_url = f"http://127.0.0.1:5000/download/{current_date}/{file.filename}"
    return jsonify({"file_url": file_url}), 200

# 文件下载接口
@app.route('/download/<date>/<filename>', methods=['GET'])
def download_file(date, filename):
    file_path = os.path.join(BASE_DIR, date, filename)

    if not os.path.exists(file_path):
        return jsonify({"error": "File not found"}), 404

    return send_file(file_path)

# 本地视频查看
@app.route('/result/video', methods=['POST'])
def result_file():
    # file_path = os.path.join(BASE_RESULT_DIR, filepath)
    path = request.json.get("filepath")
    if not os.path.exists(path):
        return jsonify({"error": "File not found"}), 404

    return send_file(path)


# 定时任务：删除一天前的文件
def delete_old_files():
    current_date = datetime.now().strftime("%Y%m%d")
    for dir_name in os.listdir(BASE_DIR):
        if dir_name < current_date:
            dir_path = os.path.join(BASE_DIR, dir_name)
            shutil.rmtree(dir_path)
            print(f"Deleted directory: {dir_path}")

# 启动定时任务
def run_scheduler():
    schedule.every().day.at("00:00").do(delete_old_files)
    while True:
        schedule.run_pending()
        time.sleep(1)





if __name__ == '__main__':
    # 启动定时任务线程
    scheduler_thread = Thread(target=run_scheduler)
    scheduler_thread.daemon = True
    scheduler_thread.start()

    # 启动Flask应用
    app.run(debug=True)



